<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <title>文档</title>
  <link href="../css/semantic/semantic.min.css" rel="stylesheet">
  <link href="../css/markdown.css" rel="stylesheet">
  <link href="../css/wtxynavigation.css" rel="stylesheet">
  <script src="../js/jquery.min.js"></script>
  <script type="text/javascript" src="../js/include.js"></script>
  <style>
    body{padding-top:0;background:#f7f7f7}
    body>.ui.container{width:100%;padding:0}
    #project-title{background:#6e6e6e;width:100%;line-height:3.572rem;color:#fff;font-size:1.2rem}
    #project-title .title-wrap{font-weight:700;padding:0 12px;width:100%;max-width:1366px!important;min-width:900px;margin:0 auto}
    #project-title .left,#project-title right{display:inline-block}
    #project-title .right{float:right}
    #project-title .right .wiki-actions .menu{left:auto;right:0;margin-top:.4em!important}
    #wiki-preview-container{width:100%;max-width:1366px!important;min-width:900px;padding:0;border:1px solid #e3e9ed;border-top:0}
    #wiki-preview>.ui.segment{margin-top:0;padding:1rem;padding-left:0;border:0}
    .hover-places{display:inline-block}
    #page-detail{width:60%;margin:0 auto}
    #page-detail .title{font-weight:700;font-size:24px;padding:12px 0;border-bottom:1px solid #ccc}
    #page-detail .content{margin-top:15px}
    .content p{word-wrap:break-word}
    #wiki-parent,#wiki-title,#wikis{display:none}
    .ui.grid{padding:0!important}
    #ex-all{cursor:pointer;color:#537c8d}
  </style>
</head>
<body>
  <div class="ui container">
    <div id="project-title">
      <div class="title-wrap">
        <div class="left">
          <i class="icon eye"></i>
          文档预览:
          mianmSDK
        </div>
        <div class="right">
          Export by Gitee
        </div>
      </div>
    </div>

    <div class="ui container" id="wiki-preview-container">
      <div id="wiki-preview">
        <div class="ui segment">
          <div id="page-detail" class="markdown-body">
            <div class='title'>25.runtime消息传递</div><div class='content'><h1>
<a id="25runtime消息传递" class="anchor" href="#25runtime%E6%B6%88%E6%81%AF%E4%BC%A0%E9%80%92"></a>25.runtime消息传递</h1>
<p><strong>关键词</strong>: <code>runtime</code>,<code>消息传递</code></p>
<h2>
<a id="描述" class="anchor" href="#%E6%8F%8F%E8%BF%B0"></a>描述</h2>
<h1>
<a id="1-objc_msgsend" class="anchor" href="#1-objc_msgsend"></a>1. objc_msgSend</h1>
<ul>
<li>
<ol>
<li>固定的两个参数: <code>id self</code> 和 <strong>方法选择器</strong> <code>SEL op</code>
</li>
</ol>
</li>
<li>
<ol start="2">
<li>后续就是实际的参数</li>
</ol>
</li>
</ul>
<pre><code>
void objc_msgSend(void /* 固定的两个参数是: id self, 方法选择器 SEL op, 后续就是参数 */);

</code></pre>
<ul>
<li>例如我们在<code>OC</code>里面写的<code>[self  setMainUI];</code>最后会转换成这样<code>objc_msgSend(self, @selector(setMainUI));</code>的函数调用.</li>
<li>第一个参数就是消息传递的接收者,也就是<code>self</code>
</li>
<li>第二个参数就是就是消息名称, 也就是选择器<code>@selector(setMainUI)</code>
</li>
</ul>
<p>我说消息传递实际上转化成了函数调用...</p>
<h1>
<a id="2-objc_msgsendsuper" class="anchor" href="#2-objc_msgsendsuper"></a>2. objc_msgSendSuper</h1>
<ul>
<li>
<ol>
<li>固定的两个参数:  <code>objc_super</code>和 <strong>方法选择器</strong> <code>SEL op</code>
</li>
</ol>
</li>
<li>
<ol start="2">
<li>后续就是实际的参数</li>
</ol>
</li>
</ul>
<pre><code>
OBJC_EXPORT id objc_msgSendSuper(struct objc_super *super, SEL op, ...)

</code></pre>
<h2>
<a id="21-objc_super" class="anchor" href="#21-objc_super"></a>2.1 objc_super</h2>
<ul>
<li>
<code>OC</code>里面的<code>super</code>(<code>[super  viewDidLoad];</code>)关键字,是编译器关键字, 经过编译器编译之后呢,就会被解析成<code>objc_super</code>结构体指针.</li>
<li>
<code>objc_super</code>结构体里面的<code>receiver</code>实际上是当前对象.</li>
</ul>
<ol>
<li>
<code>id receiver;</code> 这个<code>receiver</code>实际就是当前对象</li>
</ol>
<pre><code>
struct objc_super { 

  id receiver; 
  Class superClass;
};

</code></pre>
<p><code>[super  viewDidLoad];</code> 最终转换成了<code>objc_msgSendSuper(super, @selector(viewDidLoad));</code>
<img src="images/runtime2021051502.png" alt="runtime2021051502"></p>
<p><strong>通过上面特性,就会得到如下结果</strong>
<img src="images/runtime2021051501.png" alt="runtime2021051501"></p>
<h1>
<a id="3-objc_msgsend-和-objc_msgsendsuper区别" class="anchor" href="#3-objc_msgsend-%E5%92%8C-objc_msgsendsuper%E5%8C%BA%E5%88%AB"></a>3. <strong>objc_msgSend</strong> 和 <strong>objc_msgSendSuper</strong>区别</h1>
<ol>
<li>
<code>objc_msgSend</code>是在当前对象的<code>isa</code>指针指向的<strong>类对象</strong>中去查找方法</li>
<li>
<code>objc_msgSendSuper</code>是跳过当前对象的<code>isa</code>指针指向的<strong>类对象</strong>, 去<code>isa</code>指针指向的<strong>类对象</strong>的父类中查找</li>
</ol>
<p><img src="images/runtime2021051503.png" alt="runtime2021051503"></p>
<p><img src="../images/runtimeOCM01.png" alt="runtimeOCM01"></p></div>
          </div>
        </div>
      </div>
      </div>
  </div>
</body>
</html>